package org.nnxy.foodboot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.nnxy.foodboot.entity.UserRecipeInteraction;
import org.nnxy.foodboot.mapper.UserRecipeInteractionMapper;
import org.nnxy.foodboot.service.UserRecipeInteractionService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户食谱交互服务实现类
 */
@Service
@RequiredArgsConstructor
public class UserRecipeInteractionServiceImpl extends ServiceImpl<UserRecipeInteractionMapper, UserRecipeInteraction> implements UserRecipeInteractionService {

    private final UserRecipeInteractionMapper userRecipeInteractionMapper;

    @Override
    public UserRecipeInteraction getInteractionByUserIdAndRecipeId(Integer userId, Integer recipeId) {
        if (userId == null || recipeId == null) {
            return null;
        }
        
        LambdaQueryWrapper<UserRecipeInteraction> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRecipeInteraction::getUserId, userId)
                .eq(UserRecipeInteraction::getRecipeId, recipeId);
        
        return getOne(queryWrapper);
    }

    @Override
    public Page<UserRecipeInteraction> getUserInteractionsPage(Page<UserRecipeInteraction> page, Integer userId) {
        if (userId == null) {
            return new Page<>();
        }
        
        LambdaQueryWrapper<UserRecipeInteraction> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRecipeInteraction::getUserId, userId)
                .orderByDesc(UserRecipeInteraction::getUpdateTime);
        
        return page(page, queryWrapper);
    }

    @Override
    public boolean updateBrowseRecord(Integer userId, Integer recipeId) {
        if (userId == null || recipeId == null) {
            return false;
        }
        
        // 获取现有记录或创建新记录
        UserRecipeInteraction interaction = getInteractionByUserIdAndRecipeId(userId, recipeId);
        
        if (interaction == null) {
            // 创建新记录
            interaction = new UserRecipeInteraction();
            interaction.setUserId(userId);
            interaction.setRecipeId(recipeId);
            interaction.setBrowseCount(1);
            interaction.setLastBrowseTime(LocalDateTime.now());
            
            return save(interaction);
        } else {
            // 更新现有记录
            LambdaUpdateWrapper<UserRecipeInteraction> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(UserRecipeInteraction::getId, interaction.getId())
                    .set(UserRecipeInteraction::getLastBrowseTime, LocalDateTime.now())
                    .setSql("browse_count = browse_count + 1");
            
            return update(updateWrapper);
        }
    }

    @Override
    public boolean updateFavoriteRecord(Integer userId, Integer recipeId, Boolean isFavorite) {
        if (userId == null || recipeId == null || isFavorite == null) {
            return false;
        }
        
        // 获取现有记录或创建新记录
        UserRecipeInteraction interaction = getInteractionByUserIdAndRecipeId(userId, recipeId);
        
        if (interaction == null) {
            // 创建新记录
            interaction = new UserRecipeInteraction();
            interaction.setUserId(userId);
            interaction.setRecipeId(recipeId);
            interaction.setIsFavorite(isFavorite);
            if (isFavorite) {
                interaction.setFavoriteTime(LocalDateTime.now());
            }
            
            return save(interaction);
        } else {
            // 更新现有记录
            LambdaUpdateWrapper<UserRecipeInteraction> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(UserRecipeInteraction::getId, interaction.getId())
                    .set(UserRecipeInteraction::getIsFavorite, isFavorite);
            
            if (isFavorite) {
                updateWrapper.set(UserRecipeInteraction::getFavoriteTime, LocalDateTime.now());
            }
            
            return update(updateWrapper);
        }
    }

    @Override
    public boolean updateRatingRecord(Integer userId, Integer recipeId, BigDecimal rating, String review) {
        if (userId == null || recipeId == null || rating == null) {
            return false;
        }
        
        // 获取现有记录或创建新记录
        UserRecipeInteraction interaction = getInteractionByUserIdAndRecipeId(userId, recipeId);
        
        if (interaction == null) {
            // 创建新记录
            interaction = new UserRecipeInteraction();
            interaction.setUserId(userId);
            interaction.setRecipeId(recipeId);
            interaction.setRating(rating);
            interaction.setReview(review);
            
            return save(interaction);
        } else {
            // 更新现有记录
            LambdaUpdateWrapper<UserRecipeInteraction> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(UserRecipeInteraction::getId, interaction.getId())
                    .set(UserRecipeInteraction::getRating, rating)
                    .set(UserRecipeInteraction::getReview, review);
            
            return update(updateWrapper);
        }
    }

    @Override
    public boolean updateMakeRecord(Integer userId, Integer recipeId, String satisfactionLevel) {
        if (userId == null || recipeId == null) {
            return false;
        }
        
        // 获取现有记录或创建新记录
        UserRecipeInteraction interaction = getInteractionByUserIdAndRecipeId(userId, recipeId);
        
        if (interaction == null) {
            // 创建新记录
            interaction = new UserRecipeInteraction();
            interaction.setUserId(userId);
            interaction.setRecipeId(recipeId);
            interaction.setMakeCount(1);
            interaction.setLastMakeTime(LocalDateTime.now());
            interaction.setSatisfactionLevel(satisfactionLevel);
            
            return save(interaction);
        } else {
            // 更新现有记录
            LambdaUpdateWrapper<UserRecipeInteraction> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(UserRecipeInteraction::getId, interaction.getId())
                    .set(UserRecipeInteraction::getLastMakeTime, LocalDateTime.now())
                    .set(UserRecipeInteraction::getSatisfactionLevel, satisfactionLevel)
                    .setSql("make_count = make_count + 1");
            
            return update(updateWrapper);
        }
    }

    @Override
    public List<Integer> getMostViewedRecipeIds(Integer userId, Integer limit) {
        if (userId == null || limit == null || limit <= 0) {
            return List.of();
        }
        
        return userRecipeInteractionMapper.getMostViewedRecipeIds(userId, limit);
    }

    @Override
    public List<Integer> getFavoriteRecipeIds(Integer userId, Integer limit) {
        if (userId == null || limit == null || limit <= 0) {
            return List.of();
        }
        
        return userRecipeInteractionMapper.getFavoriteRecipeIds(userId, limit);
    }

    @Override
    public List<Integer> getHighRatedRecipeIds(Integer userId, Double minRating, Integer limit) {
        if (userId == null || minRating == null || limit == null || limit <= 0) {
            return List.of();
        }
        
        return userRecipeInteractionMapper.getHighRatedRecipeIds(userId, minRating, limit);
    }

    @Override
    public Map<String, Object> getUserInteractionStats(Integer userId) {
        if (userId == null) {
            return Map.of();
        }
        
        Map<String, Object> stats = new HashMap<>();
        
        // 计算浏览食谱数量
        LambdaQueryWrapper<UserRecipeInteraction> browseQuery = new LambdaQueryWrapper<>();
        browseQuery.eq(UserRecipeInteraction::getUserId, userId)
                .gt(UserRecipeInteraction::getBrowseCount, 0);
        long browseCount = count(browseQuery);
        stats.put("browseCount", browseCount);
        
        // 计算收藏食谱数量
        LambdaQueryWrapper<UserRecipeInteraction> favoriteQuery = new LambdaQueryWrapper<>();
        favoriteQuery.eq(UserRecipeInteraction::getUserId, userId)
                .eq(UserRecipeInteraction::getIsFavorite, true);
        long favoriteCount = count(favoriteQuery);
        stats.put("favoriteCount", favoriteCount);
        
        // 计算评分食谱数量
        LambdaQueryWrapper<UserRecipeInteraction> ratingQuery = new LambdaQueryWrapper<>();
        ratingQuery.eq(UserRecipeInteraction::getUserId, userId)
                .isNotNull(UserRecipeInteraction::getRating);
        long ratingCount = count(ratingQuery);
        stats.put("ratingCount", ratingCount);
        
        // 计算制作食谱数量
        LambdaQueryWrapper<UserRecipeInteraction> makeQuery = new LambdaQueryWrapper<>();
        makeQuery.eq(UserRecipeInteraction::getUserId, userId)
                .gt(UserRecipeInteraction::getMakeCount, 0);
        long makeCount = count(makeQuery);
        stats.put("makeCount", makeCount);
        
        return stats;
    }

    @Override
    public long getTotalBrowseCount() {
        // 计算所有用户总浏览量
        LambdaQueryWrapper<UserRecipeInteraction> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.gt(UserRecipeInteraction::getBrowseCount, 0);
        List<UserRecipeInteraction> interactions = list(queryWrapper);
        
        long totalCount = 0;
        for (UserRecipeInteraction interaction : interactions) {
            totalCount += interaction.getBrowseCount();
        }
        
        return totalCount;
    }
    
    @Override
    public long countBrowseByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime == null || endTime == null) {
            return 0;
        }
        
        // 统计指定时间范围内的浏览总次数
        LambdaQueryWrapper<UserRecipeInteraction> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(UserRecipeInteraction::getLastBrowseTime, startTime, endTime);
        List<UserRecipeInteraction> interactions = list(queryWrapper);
        
        long count = 0;
        for (UserRecipeInteraction interaction : interactions) {
            // 简单计算该时间段内的浏览量（此处为近似值）
            count += 1; // 每条记录算一次浏览
        }
        
        return count;
    }
    
    @Override
    public List<Map<String, Object>> getMostViewedRecipes(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        // 此处应该使用自定义SQL来获取最受欢迎的食谱
        // 由于复杂SQL需要在Mapper中定义，这里简化处理
        return userRecipeInteractionMapper.getMostViewedRecipes(limit);
    }
    
    @Override
    public List<Map<String, Object>> getHighestRatedRecipes(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        // 此处应该使用自定义SQL来获取评分最高的食谱
        // 由于复杂SQL需要在Mapper中定义，这里简化处理
        return userRecipeInteractionMapper.getHighestRatedRecipes(limit);
    }

    @Override
    public List<Map<String, Object>> getUserFavoriteCategories(Integer userId, int limit) {
        if (userId == null || limit <= 0) {
            return List.of();
        }
        
        return userRecipeInteractionMapper.getUserFavoriteCategories(userId, limit);
    }

    @Override
    public Map<String, Long> getUserRatingDistribution(Integer userId) {
        if (userId == null) {
            return Map.of();
        }
        
        // 获取用户所有评分记录
        LambdaQueryWrapper<UserRecipeInteraction> query = new LambdaQueryWrapper<>();
        query.eq(UserRecipeInteraction::getUserId, userId)
             .isNotNull(UserRecipeInteraction::getRating)
             .select(UserRecipeInteraction::getRating);
        
        List<UserRecipeInteraction> interactions = list(query);
        
        // 统计评分分布
        Map<String, Long> distribution = new HashMap<>();
        
        // 初始化评分级别
        for (int i = 1; i <= 5; i++) {
            distribution.put(String.valueOf(i), 0L);
        }
        
        // 统计数量
        for (UserRecipeInteraction interaction : interactions) {
            BigDecimal rating = interaction.getRating();
            if (rating != null) {
                // 向下取整作为分类
                int ratingLevel = rating.intValue();
                // 确保rating在1-5范围内
                if (ratingLevel < 1) ratingLevel = 1;
                if (ratingLevel > 5) ratingLevel = 5;
                
                String key = String.valueOf(ratingLevel);
                distribution.put(key, distribution.getOrDefault(key, 0L) + 1);
            }
        }
        
        return distribution;
    }

    @Override
    public Map<String, Long> getUserActivityByDay(Integer userId, int days) {
        if (userId == null || days <= 0) {
            return Map.of();
        }
        
        // 计算起始日期
        LocalDateTime startDate = LocalDateTime.now().minusDays(days - 1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        
        // 获取用户在指定日期范围内的交互记录
        LambdaQueryWrapper<UserRecipeInteraction> query = new LambdaQueryWrapper<>();
        query.eq(UserRecipeInteraction::getUserId, userId)
             .ge(UserRecipeInteraction::getUpdateTime, startDate)
             .select(UserRecipeInteraction::getUpdateTime);
        
        List<UserRecipeInteraction> interactions = list(query);
        
        // 初始化每天的活跃度统计
        Map<String, Long> activityByDay = new HashMap<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        
        // 初始化所有日期
        for (int i = 0; i < days; i++) {
            LocalDateTime date = startDate.plusDays(i);
            activityByDay.put(date.format(formatter), 0L);
        }
        
        // 统计每天的交互次数
        for (UserRecipeInteraction interaction : interactions) {
            if (interaction.getUpdateTime() != null) {
                String dayKey = interaction.getUpdateTime().format(formatter);
                activityByDay.put(dayKey, activityByDay.getOrDefault(dayKey, 0L) + 1);
            }
        }
        
        return activityByDay;
    }

    @Override
    public List<Map<String, Object>> getRecentInteractions(Integer userId, int limit) {
        if (userId == null || limit <= 0) {
            return List.of();
        }
        
        return userRecipeInteractionMapper.getRecentInteractions(userId, limit);
    }
} 